package com.java.thread;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
 * 工人模式
 * @author jack
 */
public class TestWorkerPattern {

	public static void main(String[] args) {
		TaskQueue taskQueue = new TaskQueue();
		for(int i=0;i<2;i++){
			taskQueue.putTask(new CalculateTask());
			taskQueue.putTask(new TimerTask());
		}
		WorkerThread th1=new WorkerThread(taskQueue);
		th1.start();
		WorkerThread th2=new WorkerThread(taskQueue);
		th2.start();
		ThreadPool threadPool = new ThreadPool();
		threadPool.addWorkerThread(th1);
		threadPool.addWorkerThread(th2);
		try {
			Thread.sleep(8000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		threadPool.currentStatus();
		
		while(true){
			int idleThreads = 0;
			List threadList = threadPool.getThreads();
			for(int i=0;i<threadList.size();i++){
				WorkerThread workerThread = (WorkerThread) threadList.get(i);
				if(workerThread.isIdle()){
					idleThreads+=1;
				}
			}
			if(idleThreads == threadList.size() && taskQueue.getQueue().size()==0){
				break;
			}
		}
		System.out.println("----------------------任务执行完毕，关闭线程，线程数："+threadPool.getThreads().size()+"---------------------------");
		for(int i=0;i<threadPool.getThreads().size();i++){
			WorkerThread workerThread = (WorkerThread) threadPool.getThreads().get(i);
			workerThread.shutdown();
			System.out.println(workerThread.getName()+":已关闭");
		}
		
		
		
	}
}


interface Task{
	void execute();
}


class CalculateTask implements Task{
	private static int count = 0 ;
	private int num = count;
	
	public CalculateTask(){
		count++;
	}
	
	@Override
	public void execute() {
		System.out.println("[CalculateTask"+num+"]start...");
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("[CalculateTask"+num+"]done.");
	}
	
}

class TimerTask implements Task{
	private static int count = 0 ;
	private int num = count;
	
	public TimerTask(){
		count++;
	}
	
	@Override
	public void execute() {
		System.out.println("[TimerTask"+num+"]start...");
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("[TimerTask"+num+"]done.");
	}
}

class TaskQueue{
	private List<Task> queue = new LinkedList<Task>();
	public synchronized Task getTask(){
		while(queue.size() == 0){
			try {
				this.wait();
			} catch (InterruptedException e) {
				WorkerThread workerThread = (WorkerThread) Thread.currentThread();
				if(workerThread.isStop()){
					System.out.println("当前线程状态为等待，由于工作队列已为空，系统进行关闭线程资源,关闭过程中出现的异常");
				}else {
					System.out.println("系统异常");
				}
				return null;
			}
		}
		return (Task)queue.remove(0);
	}
	
	public synchronized void putTask(Task task) {
		queue.add(task);
		this.notifyAll();
	}

	public List<Task> getQueue() {
		return queue;
	}

	public void setQueue(List<Task> queue) {
		this.queue = queue;
	}
}

class WorkerThread extends Thread{
	private static int count = 0;
	private boolean busy = false;
	private boolean stop = false;
	private TaskQueue queue;
	public WorkerThread(ThreadGroup threadGroup,TaskQueue queue){
		super(threadGroup,"worker-"+count);
		count++;
		this.queue = queue;
	}
	public WorkerThread(TaskQueue queue){
		super("worker-"+count);
		count++;
		this.queue = queue;
	}
	public void shutdown(){
		stop = true;
		this.interrupt();
		try {
			this.join();
		} catch (InterruptedException e) {
			System.out.println("关闭线程出现异常，线程名："+this.getName());
		}
	}
	public boolean isIdle(){
		return !busy;
	}
	public void run(){
		System.out.println(getName()+" start.");
		while(!stop){
			Task task = queue.getTask();
			if(task!=null){
				busy = true;
				task.execute();
				busy = false;
			}
		}
		System.out.println(getName()+" terminated.");
	}
	public boolean isStop() {
		return stop;
	}
}

class ThreadPool extends ThreadGroup{
	private List<Thread> threads = new LinkedList<Thread>();
	public ThreadPool(){
		super("Thread-Pool");
	}
	
	public synchronized void addWorkerThread(Thread th){
		threads.add(th);
	}
	
	public synchronized void removeWorkerThread(){
		if(threads.size() > 0){
			WorkerThread thread = (WorkerThread) threads.remove(0);
			thread.shutdown();
		}
	}
	
	public synchronized void currentStatus(){
		System.out.println("-------thread status print start--------");
		System.out.println("Thread count="+threads.size());
		Iterator it = threads.iterator();
		while(it.hasNext()){
			WorkerThread t = (WorkerThread)it.next();
			System.out.println(t.getName()+",isIdle:"+t.isIdle()+",isAlive:"+t.isAlive());
		}
		System.out.println("-------thread status print end--------");
	}

	public List<Thread> getThreads() {
		return threads;
	}

	public void setThreads(List<Thread> threads) {
		this.threads = threads;
	}

}